package com.dd.cloud.user.service.doctor.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.IntegralConstants;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.DateUtils;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.doctor.DoctorIntegral;
import com.dd.cloud.user.entity.order.OrderPay;
import com.dd.cloud.user.entity.pres.PresPrescription;
import com.dd.cloud.user.entity.resource.PostInfoOperCount;
import com.dd.cloud.user.mapper.doctor.DoctorIntegralMapper;
import com.dd.cloud.user.mq.MQConfig;
import com.dd.cloud.user.mq.RabbitSend;
import com.dd.cloud.user.req.doctor.DoctorIntegralReq;
import com.dd.cloud.user.req.doctor.SignResponse;
import com.dd.cloud.user.res.doctor.DoctorIntegraRes;
import com.dd.cloud.user.res.doctor.DoctorIntegralDataRes;
import com.dd.cloud.user.service.doctor.IDoctorIntegralService;
import com.dd.cloud.user.service.log.ILogErrorService;
import com.dd.cloud.user.service.order.IOrderPayService;
import com.dd.cloud.user.service.pres.IPresPrescriptionService;
import com.dd.cloud.user.service.resource.IPostInfoOperCountService;
import com.dd.cloud.user.util.LoginUtils;
import com.dd.cloud.user.vo.DelayMqVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 医生积分表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2023-10-07
 */
@Service
@Slf4j
public class DoctorIntegralServiceImpl extends ServiceImpl<DoctorIntegralMapper, DoctorIntegral> implements IDoctorIntegralService {

    @Autowired
    private ILogErrorService logErrorService;
    @Autowired
    private RabbitSend rabbitSend;

    @Autowired
    private RedisTemplate redisTemplate;

    public String userFamilyKey = "integral:inviteUserFamily:";

    public String studyPresKey = "integral:studyPres:";

    public String smartPresKey = "integral:smartPres";

    public String readStudyKey = "integral:readStudyKey:";

    public String shareKey = "integral:shareKey:";

    public String taskKey = "integral:taskKey:";

    public String viewKey = "integral:viewKey:";

    @Autowired
    private IOrderPayService orderPayService;

    @Autowired
    private IPresPrescriptionService presPrescriptionService;

    @Autowired
    private LoginUtils loginUtils;

    @Override
    public List<DoctorIntegraRes> queryIntegralList(DoctorIntegralReq doctorIntegralReq) {
        if (StringUtils.isBlank(doctorIntegralReq.getStatus())) {
            doctorIntegralReq.setStatus("-2,2,3");
        }
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        List<DoctorIntegral> integralList = this.getBaseMapper().queryIntegralList(doctorIntegralReq.getStatus(), loginInfo.getId(),
                LocalDate.now().plusYears(-1), LocalDate.now());
        if (CollectionUtil.isEmpty(integralList)) {
            return new ArrayList<>();
        }

        List<String> years = DateUtils.getMonthBetweenDate(LocalDate.now().plusYears(-1), LocalDate.now());
        List<DoctorIntegraRes> doctorIntegralList = new ArrayList<>();
        Map<String, List<DoctorIntegral>> map = integralList.stream().collect(Collectors.groupingBy(DoctorIntegral::getTime));
        for (int i = years.size() - 1; i >= 1; i--) {
            DoctorIntegraRes doctorIntegraRes = new DoctorIntegraRes();
            doctorIntegraRes.setData(years.get(i));
            doctorIntegraRes.setGive(0);
            doctorIntegraRes.setOut(0);
            if (CollectionUtil.isNotEmpty(map)) {
                List<DoctorIntegral> doctorIntegrals = map.get(years.get(i));
                doctorIntegraRes.setDoctorIntegralList(doctorIntegrals);
                if (CollectionUtil.isNotEmpty(doctorIntegrals)) {
                    System.out.println("Key = " + years.get(i) + ", Value = " + JSON.toJSONString(doctorIntegrals));
                    Integer give = getGiveSum(doctorIntegrals);
                    Integer out = getOutSum(doctorIntegrals);
                    log.info("日期:" + years.get(i) + "-领取积分值:" + give + "-消耗积分值:" + out);
                    doctorIntegraRes.setGive(give);
                    doctorIntegraRes.setOut(Math.abs(out));
                }
            }
            doctorIntegralList.add(doctorIntegraRes);
        }
        return doctorIntegralList;
    }

    private Integer getGiveSum(List<DoctorIntegral> value) {
        Integer sum = value.stream().filter(item -> IntegralConstants.status.RECEIVED.equals(item.getStatus())).mapToInt(DoctorIntegral::getNum).sum();
        return sum;
    }

    private Integer getOutSum(List<DoctorIntegral> value) {
        Integer sum = value.stream().filter(item -> IntegralConstants.status.USED.equals(item.getStatus())
                || IntegralConstants.status.RETURN.equals(item.getStatus())).mapToInt(DoctorIntegral::getNum).sum();
        return sum;
    }


    @Override
    public void registrationBonus(Integer type, Integer doctorId) {
        LambdaQueryWrapper<DoctorIntegral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorIntegral::getDoctorId, doctorId)
                .eq(DoctorIntegral::getTitle, IntegralConstants.IntegralType.ONE_TYPE);
        Integer count = this.count(wrapper);
        if (count > 0) {
            return;
        }
        Boolean flag = saveDoctorIntegral(type, doctorId, "注册奖励", 10);
        if (flag) {
            log.info("完善注册积分奖励获取成功");
        }
    }

    @Override
    public void fishedChecked(Integer type, Integer doctorId) {
        LambdaQueryWrapper<DoctorIntegral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorIntegral::getDoctorId, doctorId)
                .eq(DoctorIntegral::getTitle, IntegralConstants.IntegralType.TWO_TYPE);
        Integer count = this.count(wrapper);
        if (count > 0) {
            return;
        }
        Boolean flag = saveDoctorIntegral(type, doctorId, "认证奖励", 50);
        if (flag) {
            log.info("完善认证积分奖励获取成功");
        }
    }

    @Override
    public void fishedInfo(Integer type, Integer doctorId) {
        LambdaQueryWrapper<DoctorIntegral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorIntegral::getDoctorId, doctorId)
                .eq(DoctorIntegral::getTitle, IntegralConstants.IntegralType.THREE_TYPE);
        Integer count = this.count(wrapper);
        if (count > 0) {
            return;
        }
        Boolean flag = saveDoctorIntegral(type, doctorId, "完善个人信息奖励", 5);
        if (flag) {
            log.info("完善个人信息积分奖励获取成功");
        }
    }

    @Override
    public void uploadHeadImg(Integer type, Integer doctorId) {
        LambdaQueryWrapper<DoctorIntegral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorIntegral::getDoctorId, doctorId)
                .eq(DoctorIntegral::getType, type);
        Integer count = this.count(wrapper);
        if (count > 0) {
            return;
        }
        Boolean flag = saveDoctorIntegral(type, doctorId, "完善个人信息奖励", 5);
        if (flag) {
            log.info("完善个人信息积分奖励获取成功");
        }
    }

    @Override
    public void inviteDoctor(Integer type, Integer doctorId) {
        Boolean flag = false;
        if (IntegralConstants.IntegralType.FOUR_TYPE.equals(type)) {
            flag = saveDoctorIntegral(type, doctorId, "邀请医生奖励", 5);
        } else if (IntegralConstants.IntegralType.FIVE_TYPE.equals(type)) {
            flag = saveDoctorIntegral(type, doctorId, "邀请医生奖励", 50);
        }
        if (flag) {
            log.info("邀请医生积分奖励获取成功");
        }
    }

    @Override
    public void inviteUserFamily(Integer type, Integer doctorId) {
        Integer num = (Integer) redisTemplate.opsForValue().get(userFamilyKey + type + ":" + doctorId);
        if (num == null) {
            Boolean flag = saveDoctorIntegral(type, doctorId, "邀请患者奖励", 5);
            if (flag) {
                Long time = 60 * 60 * 24 * 7L;
                redisTemplate.opsForValue().set(userFamilyKey + type + ":" + doctorId, 5, time, TimeUnit.SECONDS);
                log.info("邀请患者积分奖励获取成功");
            }
        } else {
            if (num < 200) {
                Boolean flag = saveDoctorIntegral(type, doctorId, "邀请患者奖励", 5);
                if (flag) {
                    log.info("邀请患者积分奖励获取成功");
                    Long time = redisTemplate.getExpire(userFamilyKey + type + ":" + doctorId);
                    redisTemplate.opsForValue().set(userFamilyKey + type + ":" + doctorId, num + 5, time, TimeUnit.SECONDS);
                }
            }
        }
    }

    @Override
    public void fishedStudyPres(Integer type, Integer doctorId) {
        Integer num = (Integer) redisTemplate.opsForValue().get(studyPresKey + type + ":" + doctorId);
        if (num == null) {
            Boolean flag = saveDoctorIntegral(type, doctorId, "健康管理奖励", 20);
            if (flag) {
                Long time = 60 * 60 * 24 * 7L;
                redisTemplate.opsForValue().set(studyPresKey + type + ":" + doctorId, 5, time, TimeUnit.SECONDS);
                log.info("健康管理积分奖励获取成功");
            }
        } else {
            if (num < 500) {
                Boolean flag = saveDoctorIntegral(type, doctorId, "健康管理奖励", 20);
                if (flag) {
                    log.info("健康管理积分奖励获取成功");
                    Long time = redisTemplate.getExpire(studyPresKey + type + ":" + doctorId);
                    redisTemplate.opsForValue().set(studyPresKey + type + ":" + doctorId, num + 20, time, TimeUnit.SECONDS);
                }
            }
        }
    }

    @Override
    public void fishedSmartPres(Integer type, String orderNo) {
        if (IntegralConstants.IntegralType.NINE_TYPE.equals(type)) {
            Integer num = (Integer) redisTemplate.opsForValue().get(smartPresKey + type + ":" + orderNo);
            if (num == null) {
                Boolean flag = savePresIntegral(type, orderNo, "健康管理奖励", 20);
                if (flag) {
                    Long time = 60 * 60 * 24 * 7L;
                    redisTemplate.opsForValue().set(smartPresKey + type + ":" + orderNo, 20, time, TimeUnit.SECONDS);
                    log.info("健康管理积分奖励获取成功");
                }
            } else {
                if (num < 500) {
                    Boolean flag = savePresIntegral(type, orderNo, "健康管理奖励", 20);
                    if (flag) {
                        log.info("健康管理积分奖励获取成功");
                        Long time = redisTemplate.getExpire(smartPresKey + type + ":" + orderNo);
                        redisTemplate.opsForValue().set(smartPresKey + type + ":" + orderNo, num + 20, time, TimeUnit.SECONDS);
                    }
                }
            }
        } else if (IntegralConstants.IntegralType.TEN_TYPE.equals(type)) {
            savePresIntegral(type, orderNo, "健康管理奖励", 100);
        }
    }

    private Boolean savePresIntegral(Integer type, String orderNo, String title, int num) {
        OrderPay orderPay = orderPayService.getOrderPay(orderNo);
        if (orderPay == null) {
            return false;
        }
        PresPrescription presPrescription = presPrescriptionService.getById(orderPay.getServerNo());
        if (presPrescription == null) {
            return false;
        }
        log.info("~进入开方获取积分方法~");
        DoctorIntegral doctorIntegral = new DoctorIntegral();
        doctorIntegral.setTitle("健康管理奖励").setDoctorId(presPrescription.getDoctorId())
                .setType(type)
                .setStatus(IntegralConstants.status.AWAITING)
                .setType(type)
                .setEndDate(LocalDateTime.now().plusDays(1))
                .setCreateDate(LocalDateTime.now())
                .setOrderNo(orderNo)
                .setTencode(presPrescription.getTencode())
                .setNum(num);
        Boolean flag = this.save(doctorIntegral);
        if (!flag) {
            logErrorService.presBackLog("积分奖励失败", "保存积分失败", "doctorId=" + presPrescription.getDoctorId() + ",type=" + type);
        }
        if (flag) {
            log.info("~开方积分获取成功~打印日志~");
            //毫秒级 24小时
            DelayMqVo<Integer> delayMqVo = new DelayMqVo<>();
            delayMqVo.setT(doctorIntegral.getId());
            delayMqVo.setType(DelayMqVo.DelayMqVoType.DOCTOR_INTEGRAL_MSG);
            long ms2 = 1000 * 60 * 60 * 24;
            rabbitSend.sendMessageDelay(MQConfig.DELAY_EXCHANGE, MQConfig.DELAY_KEY, delayMqVo, ms2);
        }
        return flag;
    }

    @Override
    public void readIntegral(Integer type, Integer doctorId) {
        Integer num = (Integer) redisTemplate.opsForValue().get(readStudyKey + type + ":" + doctorId);
        if (num == null) {
            Boolean flag = saveDoctorIntegral(type, doctorId, "学习奖励", 5);
            if (flag) {
                Long time = 60 * 60 * 24 * 7L;
                redisTemplate.opsForValue().set(readStudyKey + type + ":" + doctorId, 5, time, TimeUnit.SECONDS);
                log.info("学习积分奖励获取成功");
            }
        } else {
            if (num < 100) {
                Boolean flag = saveDoctorIntegral(type, doctorId, "学习奖励", 5);
                if (flag) {
                    log.info("学习积分奖励获取成功");
                    Long time = redisTemplate.getExpire(readStudyKey + type + ":" + doctorId);
                    redisTemplate.opsForValue().set(readStudyKey + type + ":" + doctorId, num + 5, time, TimeUnit.SECONDS);
                }
            }
        }
    }

    public Boolean saveDoctorIntegral(Integer type, Integer doctorId, String title, Integer num) {
        DoctorIntegral doctorIntegral = new DoctorIntegral();
        doctorIntegral.setTitle(title).setDoctorId(doctorId)
                .setType(type)
                .setStatus(IntegralConstants.status.AWAITING)
                .setType(type)
                .setEndDate(LocalDateTime.now().plusDays(1))
                .setCreateDate(LocalDateTime.now())
                .setNum(num);
        Boolean flag = this.save(doctorIntegral);
        if (!flag) {
            logErrorService.presBackLog("积分奖励失败", "保存积分失败", "doctorId=" + doctorId + ",type=" + type);
        }
        if (flag) {
            //毫秒级 24小时
            DelayMqVo<Integer> delayMqVo = new DelayMqVo<>();
            delayMqVo.setT(doctorIntegral.getId());
            delayMqVo.setType(DelayMqVo.DelayMqVoType.DOCTOR_INTEGRAL_MSG);
            long ms2 = 1000 * 60 * 60 * 24;
            rabbitSend.sendMessageDelay(MQConfig.DELAY_EXCHANGE, MQConfig.DELAY_KEY, delayMqVo, ms2);
        }
        return flag;
    }

    @Override
    public void login(Integer type, Integer doctorId) {
        //检查用户今天是否登录
        Boolean flag = loginUtils.checkSign(doctorId + "");
        if (flag) {
            return;
        }
        Boolean flag1 = saveDoctorIntegral(type, doctorId, "活跃奖励", 2);
        if (flag1) {
            log.info("活跃积分奖励获取成功");
        }
        //记录连续数
        SignResponse signResponse = loginUtils.signWithUserId(doctorId + "");
        long day = signResponse.getConSignInDay();
        //连续登录7天奖励
        if (day == 7) {
            Boolean flag2 = saveDoctorIntegral(type, doctorId, "活跃奖励", 5);
            if (flag2) {
                log.info("连续登录7天额外奖励获取成功");
            }
        }
    }

    @Override
    public void share(Integer type, Integer doctorId) {
        Integer num = (Integer) redisTemplate.opsForValue().get(shareKey + type + ":" + doctorId);
        if (num == null) {
            Boolean flag = saveDoctorIntegral(type, doctorId, "活跃奖励", 10);
            if (flag) {
                Long time = 60 * 60 * 24 * 7L;
                redisTemplate.opsForValue().set(shareKey + type + ":" + doctorId, 10, time, TimeUnit.SECONDS);
                log.info("学习积分奖励获取成功");
            }
        } else {
            if (num < 100) {
                Boolean flag = saveDoctorIntegral(type, doctorId, "活跃奖励", 10);
                if (flag) {
                    log.info("学习积分奖励获取成功");
                    Long time = redisTemplate.getExpire(shareKey + type + ":" + doctorId);
                    redisTemplate.opsForValue().set(shareKey + type + ":" + doctorId, num + 10, time, TimeUnit.SECONDS);
                }
            }
        }
    }

    @Override
    public void updateStatus(Integer id, Integer status) {
        DoctorIntegral doctorIntegral = this.getById(id);
        if (doctorIntegral == null) {
            return;
        }
        if (!IntegralConstants.status.AWAITING.equals(doctorIntegral.getStatus())) {
            return;
        }
        doctorIntegral.setStatus(status);
        if (IntegralConstants.status.RECEIVED.equals(status)) {
            doctorIntegral.setGiveDate(LocalDateTime.now());
        }
        Boolean flag = this.updateById(doctorIntegral);
        if (!flag) {
            log.info("更新积分状态失败!");
        }
    }

    @Override
    public List<DoctorIntegral> queryIntegralHomeList() {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        LambdaQueryWrapper<DoctorIntegral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorIntegral::getDoctorId, loginInfo.getId())
                .eq(DoctorIntegral::getStatus, IntegralConstants.status.AWAITING)
                .select(DoctorIntegral::getId, DoctorIntegral::getNum, DoctorIntegral::getType, DoctorIntegral::getTitle)
                .orderByAsc(DoctorIntegral::getCreateDate);
        return this.list(wrapper);
    }

    @Autowired
    private IPostInfoOperCountService postInfoOperCountService;

    @Override
    public void insertReadIntegral(Integer type, Integer doctorId, Integer postId) {
        if (!(IntegralConstants.IntegralType.ELEVEN_TYPE.equals(type)
                || IntegralConstants.IntegralType.FIFTEEN_TYPE.equals(type))
                || IntegralConstants.IntegralType.TWENTY_ONE.equals(type)
                || IntegralConstants.IntegralType.TWENTY_TWO.equals(type)) {
            throw new ZekeException("传递类型异常");
        }
        if (IntegralConstants.IntegralType.TWENTY_ONE.equals(type)) {
            LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
            Integer userId = loginInfo.getId();
            Integer userType = loginInfo.getType();
            LambdaQueryWrapper<PostInfoOperCount> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PostInfoOperCount::getType, 1)
                    .eq(PostInfoOperCount::getPostInfoId, postId)
                    .eq(PostInfoOperCount::getUserId, userId)
                    .eq(PostInfoOperCount::getUserType, userType);
            Integer count = postInfoOperCountService.count(queryWrapper);
            if (count > 0) {
                return;
            }
        }
        String params = type + "-" + doctorId;
        log.info("学习奖励积分,参数为{}", params);
        rabbitSend.sendMessage(MQConfig.INTEGRAL_EXCHANGE, MQConfig.INTEGRAL_QUEUE, params);
    }

    @Override
    public Integer queryIntegralUseTotal() {
//        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
//        LambdaQueryWrapper<DoctorIntegral> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(DoctorIntegral::getDoctorId, loginInfo.getId())
//                .in(DoctorIntegral::getStatus, IntegralConstants.status.RECEIVED, IntegralConstants.status.USED, IntegralConstants.status.RETURN);
//        List<DoctorIntegral> doctorIntegrals = this.list(wrapper);
//        Integer sum = 0;
//        if (CollectionUtil.isNotEmpty(doctorIntegrals)) {
////            sum = doctorIntegrals.stream().mapToInt(DoctorIntegral::getNum).sum();
//        }
//        if (sum < 0) {
//            sum = 0;
//        }
//        return sum;
        DoctorIntegralDataRes dataRes = queryDoctorIntegral();
        return dataRes.getHave() == null ? 0 : dataRes.getHave();
    }

    @Override
    public void addDoctorIntegral(OrderPay orderPay) {
        String serverNo = orderPay.getServerNo();
        PresPrescription presPrescription = presPrescriptionService.getById(serverNo);
        if (presPrescription == null) {
            log.info("处方不存在");
            return;
        }
        if (presPrescription.getIsAiPres() == 1) {
            String params = IntegralConstants.IntegralType.NINE_TYPE + "-" + orderPay.getOrderNo();
            log.info("使用智能辩证开方奖励积分,参数:{}", params);
            rabbitSend.sendMessage(MQConfig.INTEGRAL_EXCHANGE, MQConfig.INTEGRAL_QUEUE, params);
        } else {
            String params = IntegralConstants.IntegralType.TEN_TYPE + "-" + orderPay.getOrderNo();
            log.info("自主开方奖励积分,参数:{}", params);
            rabbitSend.sendMessage(MQConfig.INTEGRAL_EXCHANGE, MQConfig.INTEGRAL_QUEUE, params);
        }
    }

    @Override
    public void refundIntegral(OrderPay orderPay) {
        String serverNo = orderPay.getServerNo();
        PresPrescription presPrescription = presPrescriptionService.getById(serverNo);
        if (presPrescription == null) {
            log.info("处方不存在");
            return;
        }
        String params = IntegralConstants.IntegralType.NINETEEN_TYPE + "-" + orderPay.getOrderNo();
        log.info("退款回收,参数:{}", params);
        rabbitSend.sendMessage(MQConfig.INTEGRAL_EXCHANGE, MQConfig.INTEGRAL_QUEUE, params);
    }


    /**
     * 退款积分收回
     */
    @Override
    public void refund(String orderNo) {
        OrderPay orderPay = orderPayService.getOrderPay(orderNo);
        if (orderPay == null) {
            log.info("~处方退款,订单不存在");
            logErrorService.presBackLog("处方退款,订单不存在", "订单不存在", "订单号:orderNo=" + orderNo);
            return;
        }
        String serverNo = orderPay.getServerNo();
        PresPrescription presPrescription = presPrescriptionService.getById(serverNo);
        if (presPrescription == null) {
            log.info("~处方退款,处方不存在~");
            logErrorService.presBackLog("处方退款,处方不存在", "处方不存在", "订单号:orderNo=" + orderNo);
            return;
        }
        //查询积分
        LambdaQueryWrapper<DoctorIntegral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorIntegral::getOrderNo, orderNo)
                .eq(DoctorIntegral::getTencode, serverNo)
                .in(DoctorIntegral::getStatus, IntegralConstants.status.RECEIVED, IntegralConstants.status.AWAITING)
                .last("limit 1");
        DoctorIntegral doctorIntegral = this.getOne(wrapper);
        if (doctorIntegral == null) {
            log.info("~处方退款,积分记录不存在~");
            return;
        }
        if (IntegralConstants.status.RECEIVED.equals(doctorIntegral.getStatus())) {
            DoctorIntegral newDoctorIntegral = new DoctorIntegral();
            newDoctorIntegral.setStatus(IntegralConstants.status.RETURN)
                    .setTitle("退款积分收回")
                    .setDoctorId(doctorIntegral.getDoctorId())
                    .setTencode(doctorIntegral.getTencode())
                    .setOrderNo(orderNo)
                    .setNum(-doctorIntegral.getNum())
                    .setType(IntegralConstants.IntegralType.NINETEEN_TYPE)
                    .setCreateDate(LocalDateTime.now())
                    .setGiveDate(LocalDateTime.now());
            this.save(newDoctorIntegral);
        } else if (IntegralConstants.status.AWAITING.equals(doctorIntegral.getStatus())) {
            doctorIntegral.setStatus(IntegralConstants.status.DEL);
            this.updateById(doctorIntegral);
        }
    }

    @Override
    public DoctorIntegralDataRes queryDoctorIntegral() {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        LambdaQueryWrapper<DoctorIntegral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorIntegral::getDoctorId, loginInfo.getId())
                .in(DoctorIntegral::getStatus, IntegralConstants.status.RECEIVED,
                        IntegralConstants.status.USED,
                        IntegralConstants.status.RETURN);
        List<DoctorIntegral> doctorIntegrals = this.list(wrapper);
        //获取获取到的积分
        DoctorIntegralDataRes dataRes = new DoctorIntegralDataRes();
        if (CollectionUtil.isNotEmpty(doctorIntegrals)) {
            Integer received = selectDoctorIntegral(IntegralConstants.status.RECEIVED, doctorIntegrals);
            Integer ret = selectDoctorIntegral(IntegralConstants.status.RETURN, doctorIntegrals);
            Integer use = selectDoctorIntegral(IntegralConstants.status.USED, doctorIntegrals);
            Integer have = received + use + ret;
            dataRes.setHave(have);
            dataRes.setUse(use + ret);
            dataRes.setGive(received);
        } else {
            dataRes.setGive(0);
            dataRes.setUse(0);
            dataRes.setHave(0);
        }
        return dataRes;
    }

    @Override
    public List<DoctorIntegral> queryDoctorIntegralList(Integer doctorId) {
        LambdaQueryWrapper<DoctorIntegral> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DoctorIntegral::getStatus, 2)
                .eq(DoctorIntegral::getDoctorId, doctorId)
                .orderByDesc(DoctorIntegral::getCreateDate);
        List<DoctorIntegral> doctorIntegrals = this.list(queryWrapper);
        return doctorIntegrals;
    }


    @Override
    public void readTaskIntegral(Integer doctorId, Integer type) {
        Integer num = (Integer) redisTemplate.opsForValue().get(taskKey + type + ":" + doctorId);
        if (num == null) {
            Boolean flag = saveDoctorIntegral(type, doctorId, "学习奖励", 10);
            if (flag) {
                Long time = 60 * 60 * 24 * 7L;
                redisTemplate.opsForValue().set(taskKey + type + ":" + doctorId, 10, time, TimeUnit.SECONDS);
                log.info("学习积分奖励获取成功");
            }
        } else {
            if (num < 70) {
                Boolean flag = saveDoctorIntegral(type, doctorId, "学习奖励", 10);
                if (flag) {
                    log.info("学习积分奖励获取成功");
                    Long time = redisTemplate.getExpire(taskKey + type + ":" + doctorId);
                    redisTemplate.opsForValue().set(taskKey + type + ":" + doctorId, num + 10, time, TimeUnit.SECONDS);
                }
            }
        }
    }

    @Override
    public void view(Integer doctorId, Integer type) {
        Integer num = (Integer) redisTemplate.opsForValue().get(viewKey + type + ":" + doctorId);
        if (num == null) {
            Boolean flag = saveDoctorIntegral(type, doctorId, "活跃奖励", 2);
            if (flag) {
                Long time = 60 * 60 * 24 * 7L;
                redisTemplate.opsForValue().set(viewKey + type + ":" + doctorId, 2, time, TimeUnit.SECONDS);
                log.info("活跃积分奖励获取成功");
            }
        } else {
            if (num < 20) {
                Boolean flag = saveDoctorIntegral(type, doctorId, "活跃奖励", 2);
                if (flag) {
                    log.info("活跃积分奖励获取成功");
                    Long time = redisTemplate.getExpire(viewKey + type + ":" + doctorId);
                    redisTemplate.opsForValue().set(viewKey + type + ":" + doctorId, num + 2, time, TimeUnit.SECONDS);
                }
            }
        }
    }


    @Override
    public void award(Integer doctorId, Integer type) {
        if (IntegralConstants.IntegralType.TWENTY_FOUR.equals(type)) {
            saveDoctorIntegral(type, doctorId, "活跃奖励", 200);
        } else if (IntegralConstants.IntegralType.TWENTY_FIVE.equals(type)) {
            saveDoctorIntegral(type, doctorId, "活跃奖励", 1000);
        } else if (IntegralConstants.IntegralType.TWENTY_SIX.equals(type)) {
            saveDoctorIntegral(type, doctorId, "活跃奖励", 2000);
        }
    }

    @Override
    public void updateDoctorIntegtal() {
        List<DoctorIntegral> list = this.list();
        if (CollectionUtil.isNotEmpty(list)) {
            list.stream().forEach(item -> {
                if (item.getTitle().contains("积分")) {
                    item.setTitle(item.getTitle().replace("积分", ""));
                }
            });
            this.updateBatchById(list);
        }
    }


    private Integer selectDoctorIntegral(Integer status, List<DoctorIntegral> doctorIntegralList) {
        List<DoctorIntegral> list = doctorIntegralList.stream().filter(item -> status.equals(item.getStatus())).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(list)) {
            return list.stream().mapToInt(DoctorIntegral::getNum).sum();
        } else {
            return 0;
        }
    }
}
